iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
Modern Web

Angular 全集中筆記系列 第 23

第 23 型 - 響應式表單 (Reactive Forms)

  • 分享至 

  • xImage
  •  

相較於範本驅動表單 (Template-Driven Form) 利用表單樣版讓 Angular 產生對應的表單模型,響應式表單 (Reactive Form) 則是著重在表單模型的定義。這一篇將利用響應式表單 (Ractive Form) 開發待辦事項的表單。

前置作業

首先,先利用 Angular CLI 新增 TaskForm 元件,將待辦事項表單皆在此元件進行實作,並將其使用在 app.component.html 中。

<app-page-container>
  <app-page-title pageTitle="待辦事項清單"></app-page-title>
  <div>
    <app-task-list></app-task-list>
    <app-task-form></app-task-form>
  </div>
</app-page-container>
div {
  display: flex;
  justify-content: space-between;
}

div *:first-child {
  margin-right: 10px;
  width: 65%;
}

div *:last-child {
  width: 35%;
}

另外,也在 app.component.css 加入所需要的樣式,使結果如下圖所示。

Result

利用響應式表單 (Ractive Form) 定義待辦事項表單

在使用響應式表單 (Ractive Form) 開發前,需在 task.module.ts 加入 ReactiveFormsModule 模組。

@NgModule({
  imports: [CommonModule, HttpClientModule, FormsModule, ReactiveFormsModule],
  declarations: [
    TaskComponent,
    TaskStateColorDirective,
    TaskListComponent,
    TaiwanDatePipe,
    TaskFormComponent,
  ],
  exports: [TaskComponent, TaskListComponent, TaskFormComponent],
})
export class TaskModule {}

在範本驅動表單 (Template-Driven Form) 中,在使用了 NgForm、NgModelGroup 與 NgModel 指令頁面樣版;Angular 會將 NgForm 與 NgModelGroup 建立為表單群組 (FormGroup) 實體,NgModel 則建立表單控制項 (FormControl) 實體。而在響應式表單 (Ractive Form) 中,則會是宣告與建立 FromGroup 與 FormControl 實體,並利用所對應的指令把表單模型與頁面連結起來。

首先,在 task-form.component.ts 中宣告 FormGroup 屬性,此為整個表單最上層的群組,並將主旨、狀態與等級等資料透過建構式的第一個參數定義為 FormControl 型別。

@Component({
  selector: "app-task-form",
  templateUrl: "./task-form.component.html",
  styleUrls: ["./task-form.component.css"],
})
export class TaskFormComponent implements OnInit {
  form: FormGroup;

  constructor() {}

  ngOnInit(): void {
    this.form = new FormGroup({
      subject: new FormControl(),
      state: new FormControl(0),
      level: new FormControl(),
    });
  }
}

接著,在 task-form.component.html 中定義表單的頁面結構,透過 FormGroup 指令可以將頁面樣版連結至一表單群組;而在此表單群組 (FormGroup) 中,則會利用 FormControlName 與 FormGroupName 指令來連結表單控制項 (FormControl) 或表單群組 (FormGroup)。

<form [formGroup]="form">
  <div class="form-field">
    <label>主旨</label>
    <input type="text" formControlName="subject" />
  </div>
  <div class="form-field">
    <label>等級</label>
    <select formControlName="level">
      <option value=""></option>
      <option value="XS">XS</option>
      <option value="S">S</option>
      <option value="M">M</option>
      <option value="L">L</option>
      <option value="XL">XL</option>
    </select>
  </div>
</form>
<pre>{{ form.value | json }}</pre>

最後,為了讓實作結果能更明顯的效果,在 task-form.component.css 中加入所需的樣式。

form {
  padding: 20px;
}

div.form-field {
  padding: 10px 20px 10px 0;
  margin: 5px 0;
  display: flex;
}

div.form-field label {
  display: inline-block;
  width: 80px;
  height: 22px;
  line-height: 22px;
  text-align: center;
}

div.form-field input,
div.form-field select {
  flex-grow: 1;
}

Form

利用 FormBuilder 建構表單模型

除了利用 new 關鍵字來建立 FormGroup 實體外,Angular 還提供了 FormBuilder 服務元件來建立表單模型;因此,可以在 task-form.component.ts 注入 FormBuilder 服務元件,並利用此服務元件來建立待辦事項表單。

@Component({
  selector: "app-task-form",
  templateUrl: "./task-form.component.html",
  styleUrls: ["./task-form.component.css"],
})
export class TaskFormComponent implements OnInit {
  form: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.form = this.fb.group({
      subject: this.fb.control(undefined),
      state: this.fb.control(0),
      level: this.fb.control(undefined),
    });
  }
}

結論

這一篇利用了響應式表單 (Ractive Form) 定義待辦事項表單,而在待辦事項中還有標籤資訊,且此資訊為一陣列;此時會需要使用到響應式表單 (Ractive Form) 中的表單陣列 (FormArray) 進行定義。


上一篇
第 22 型 - 範本驅動表單 (Template-Driven Form) - 表單驗證
下一篇
第 24 型 - 響應式表單 (Reactive Form) - 表單陣列
系列文
Angular 全集中筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言